﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ThermalEquipmentDesign.Model.Condenser.EvaporaterR717
{
    class EvaporaterR717Model
    {
        EvaporaterR717Result res = new EvaporaterR717Result();
        EvaporaterR717 condenser;

        /// <summary>
        /// Calculate Evaporative Condenser
        /// </summary>
        /// <param name="con">EvaporaterR717 object</param>
        /// <returns>EvaporaterR717Result object</returns>
        public EvaporaterR717Result ImplementCalculation(EvaporaterR717 con)
        {
            condenser = con;
            res.dbHeatCapacity = CalculateHeatCapacity();
            res.dbLimitTemp = CalculateLimitTemp();
            res.dbCondensationTemp = CalculateCondensationTemp();
            res.dbAirDensity = CalculateAirDensity();
            res.dbAirFlow = CalculateAirFlow();
            res.dbOutEnthalpy = CalculateOutEnthalpy();
            res.dbOutHeatCoefficient = CalculateOutHeatCoefficient();
            res.dbSolventHeatDensity = CalculateSolventHeatDensity();
            res.dbInHeatCoefficient = CalculateInHeatCoefficient();
            res.dbHeatTransferCoefficient = CalculateHeatTransferCoefficient();
            res.dbWaterTemp = CalculateWaterTemp();
            return res;
        }

        public EvaporaterR717Result ImplementCalculation1(double dbSaturationEnthalpy)
        {
            res.dbSaturationEnthalpy = dbSaturationEnthalpy;
            res.dbAverageEnthalpy = CalculateAverageEnthalpy();            
            res.dbExterTransferArea = CalculateExterTransferArea();
            res.dbOutWaterQuantity = CalculateOutWaterQuantity();
            res.dbEvaporateWaterQuantity = CalculateEvaporateWaterQuantity();
            res.dbAirWaterQuantity = CalculateAirWaterQuantity();
            res.dbTotalPipeLenght = CalculateTotalPipeLenght();
            res.dbPipeNumber = CalculatePipeNumber();
            res.dbHorizontalPipeArea = CalculateHorizontalPipeArea();
            res.dbPipeWidth = CalculatePipeWidth();
            res.dbUnitPipeNumber = CalculateUnitPipeNumber();
            res.dbVerticalPipeArea = CalculateVerticalPipeArea();
            res.dbPipeHeigh = CalculatePipeHeigh();
            res.dbAirArea = CalculateAirArea();
            return res;
        }
        /// <summary>
        /// Calculate heat capacity
        /// </summary>
        /// <returns>heat capacity</returns>
        private double CalculateHeatCapacity()
        {
            double Qk = 1.2 * condenser.dbColdProductivity;
            return Math.Round(Qk, 2);
        }

        /// <summary>
        /// Calculate limitted cooling temperature
        /// </summary>
        /// <returns>limitted cooling temperature</returns>
        private double CalculateLimitTemp()
        {
            double tgh = condenser.dbWetTemp;
            return tgh;
        }

        /// <summary>
        /// Calculate condensation temperature
        /// </summary>
        /// <returns>condensation temperature</returns>
        private double CalculateCondensationTemp()
        {
            double tk = res.dbLimitTemp + 4.4 + 3;
            return tk;
        }

        /// <summary>
        /// Calculate density of air
        /// </summary>
        /// <returns>density of air</returns>
        private double CalculateAirDensity()
        {
            double pkk = 9.81 * Math.Pow(10, 4) * (1 + condenser.dbInAirHumidity) / (287 * (condenser.dbTemperature + 273.15) * (1 + 1.61 * condenser.dbInAirHumidity));
            return Math.Round(pkk, 2);
        }

        /// <summary>
        /// Calculate air flow
        /// </summary>
        /// <returns>air flow</returns>
        private double CalculateAirFlow()
        {
            double mkk = 3.25 * res.dbAirDensity * res.dbHeatCapacity * Math.Pow(10, -2);
            return Math.Round(mkk, 2);
        }

        /// <summary>
        /// Calculate enthalpy of outputted air
        /// </summary>
        /// <returns>enthalpy of outputted air</returns>
        private double CalculateOutEnthalpy()
        {
            double h2 = condenser.dbInEnthalpy + (res.dbHeatCapacity / res.dbAirFlow);
            return Math.Round(h2, 2);
        }

        /// <summary>
        /// Calculate external calorific coefficient
        /// </summary>
        /// <returns>external calorific coefficient</returns>
        private double CalculateOutHeatCoefficient()
        {
            double alpha = condenser.dbCorrectionCoefficient * 9750 * Math.Pow(condenser.dbHydraulicDischarge, 1.0 / 3.0);
            return Math.Round(alpha, 2);
        }

        /// <summary>
        /// Calculate heat density to solvent
        /// </summary>
        /// <returns>heat density to solvent</returns>
        private double CalculateSolventHeatDensity()
        {
            double q2 = condenser.dbWaterHeatDensity * (condenser.dbExterDiameter / condenser.dbInterDiameter);
            return Math.Round(q2, 2);
        }

        /// <summary>
        /// Calculate calorific coefficient to solvent
        /// </summary>
        /// <returns>calorific coefficient to solvent</returns>
        private double CalculateInHeatCoefficient()
        {
            double alpha = 9733 * Math.Pow(res.dbSolventHeatDensity, -0.2) * Math.Pow(condenser.dbInterDiameter, -0.3);
            return Math.Round(alpha, 2);
        }

        /// <summary>
        /// Calculate heat transfer coefficient
        /// </summary>
        /// <returns>heat transfer coefficient</returns>
        private double CalculateHeatTransferCoefficient()
        {
            double k = 1 / ((1 / res.dbInHeatCoefficient) * (condenser.dbExterDiameter / condenser.dbInterDiameter) + 1.127 * Math.Pow(10, -3) + (1 / res.dbOutHeatCoefficient));
            return Math.Round(k, 2);
        }

        /// <summary>
        /// Calculate cooling temperature of water
        /// </summary>
        /// <returns>cooling temperature of water</returns>
        private double CalculateWaterTemp()
        {
            double tw = res.dbCondensationTemp - (condenser.dbWaterHeatDensity / res.dbHeatTransferCoefficient);
            return Math.Round(tw, 2);
        }

        /// <summary>
        /// Calculate enthalpy of saturation air
        /// </summary>
        /// <returns>enthalpy of saturation air</returns>
        private double CalculateSaturationEnthalpy()
        {
            //
            return 1;
        }

        /// <summary> 
        /// Calculate average enthalpy of air
        /// </summary>
        /// <returns>average enthalpy of air</returns>
        private double CalculateAverageEnthalpy()
        {
            double htb = res.dbSaturationEnthalpy - ((res.dbOutEnthalpy - condenser.dbInEnthalpy) / (Math.Log((res.dbSaturationEnthalpy - condenser.dbInEnthalpy) / (res.dbSaturationEnthalpy - res.dbOutEnthalpy))));
            return Math.Round(htb,2);
        }


        /// <summary>
        /// Calculate external surface area of pipe
        /// </summary>
        /// <returns>external surface area of pipe</returns>
        private double CalculateExterTransferArea()
        {
            double F1 = res.dbHeatCapacity * Math.Pow(10, 3) / condenser.dbWaterHeatDensity;
            return Math.Round(F1,2);
        }

        /// <summary>
        /// Calculate amount of sprayed water
        /// </summary>
        /// <returns>amount of sprayed water</returns>
        private double CalculateOutWaterQuantity()
        {
            double M = 2.3 * (res.dbHeatCapacity / 100);
            return Math.Round(M,2);
        }

        /// <summary>
        /// Calculate amount of evaporated water
        /// </summary>
        /// <returns>amount of evaporated water</returns>
        private double CalculateEvaporateWaterQuantity()
        {
            double Mb = res.dbAirFlow * (condenser.dbOutAirHumidity - condenser.dbInAirHumidity);
            return Math.Round(Mb,2);
        }

        /// <summary>
        /// Calculate total amount of water entrained air
        /// </summary>
        /// <returns>total amount of water entrained air</returns>
        private double CalculateAirWaterQuantity()
        {
            double Mbt = 1.1 * res.dbEvaporateWaterQuantity;
            return Math.Round(Mbt,2);
        }

        /// <summary>
        /// Calculate total lenght of pipe on horizontal
        /// </summary>
        /// <returns>total lenght of pipe on horizontal</returns>
        private double CalculateTotalPipeLenght()
        {
            double L = res.dbOutWaterQuantity / (2 * condenser.dbHydraulicDischarge);
            return Math.Round(L,2);
        }

        /// <summary>
        /// Calculate number of pipe on horizontal
        /// </summary>
        /// <returns>number of pipe on horizontal</returns>
        private double CalculatePipeNumber()
        {
            double z = res.dbTotalPipeLenght / condenser.dbPipeLenght;
            return Math.Round(z, 0);
        }

        /// <summary>
        /// Calculate horizontal pitch of pipe
        /// </summary>
        /// <returns>horizontal pitch of pipe</returns>
        private double CalculateHorizontalPipeArea()
        {
            double S2 = 2 * condenser.dbExterDiameter;
            return S2;
        }

        /// <summary>
        /// Calculate width of pipe
        /// </summary>
        /// <returns>width of pipe</returns>
        private double CalculatePipeWidth()
        {
            double B = res.dbPipeNumber * res.dbHorizontalPipeArea;
            return Math.Round(B,2);
        }

        /// <summary>
        /// Calculate number of pipe for an unit
        /// </summary>
        /// <returns>number of pipe for an unit</returns>
        private double CalculateUnitPipeNumber()
        {
            double nd = res.dbExterTransferArea / (3.14 * condenser.dbExterDiameter * res.dbPipeNumber * condenser.dbPipeLenght);
            return Math.Round(nd, 0);
        }

        /// <summary>
        /// Calculate vertical pitch of pipe
        /// </summary>
        /// <returns>vertical pitch of pipe</returns>
        private double CalculateVerticalPipeArea()
        {
            double S1 = (Math.Pow(3, 1.0 / 2.0) / 2) * res.dbHorizontalPipeArea;
            return Math.Round(S1,2);
        }

        /// <summary>
        /// Calculate heigh of pipe
        /// </summary>
        /// <returns>heigh of pipe</returns>
        private double CalculatePipeHeigh()
        {
            double h = res.dbVerticalPipeArea * res.dbUnitPipeNumber;
            return Math.Round(h,2);
        }

        /// <summary>
        /// Calculate area for passing of air
        /// </summary>
        /// <returns>area for passing of air</returns>
        private double CalculateAirArea()
        {
            double Fkk = condenser.dbPipeLenght * res.dbPipeWidth - condenser.dbPipeLenght * condenser.dbExterDiameter * res.dbPipeNumber;
            return Math.Round(Fkk,2);
        }
    }
}
